package com.coffee.core.util;

import com.alibaba.fastjson.JSON;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 手机号工具类
 *
 * @author Xulg
 * Created in 2018-06-14 8:52
 */
public class PhoneNumberUtils {

    /**
     * 正则：手机号（精确）
     * <p>移动：134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、178、182、183、184、187、188、198</p>
     * <p>联通：130、131、132、145、155、156、175、176、185、186、166</p>
     * <p>电信：133、153、173、177、180、181、189、199</p>
     * <p>全球星：1349</p>
     * <p>虚拟运营商：170</p>
     */
    private static final String REGEX_MOBILE = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$";

    /**
     * 查询手机归属地的聚合接口地址
     */
    private static final String url = "http://apis.juhe.cn/mobile/get";

    /**
     * 查询手机归属地的聚合接口key
     */
    private static final String key = "7ecc6080360bb8430048cdc03391d971";

    /**
     * 校验手机号格式
     *
     * @param mobile the phone number
     * @return is match phone number format
     */
    @SuppressWarnings("all")
    public static boolean isPhoneNumber(String mobile) {
        return mobile == null ? false : mobile.matches(REGEX_MOBILE);
    }

    /**
     * 手机号的归属地省份信息
     *
     * @param mobile the phone number
     * @return the number location(浙江、江苏......)
     */
    @SuppressWarnings("all")
    public static String phoneNumberProvince(String mobile) {
        Map<String, Object> response = queryInfo(mobile);
        if (response == null || response.isEmpty()) {
            return null;
        }
        Map<String, Object> result = (Map<String, Object>) response.get("result");
        // 号码归属地省份
        return (String) result.get("province");
    }

    /**
     * 手机号的归属地区信息
     *
     * @param mobile the phone number
     * @return the number location(杭州、金华......)
     */
    @SuppressWarnings("all")
    public static String phoneNumberCity(String mobile) {
        Map<String, Object> response = queryInfo(mobile);
        if (response == null || response.isEmpty()) {
            return null;
        }
        Map<String, Object> result = (Map<String, Object>) response.get("result");
        // 号码归属地区信息
        return (String) result.get("city");
    }


    /**
     * 手机号的运营商信息
     *
     * @param mobile the phone number
     * @return the number location(移动、联通、电信)
     */
    @SuppressWarnings("all")
    public static String phoneNumberCompany(String mobile) {
        Map<String, Object> response = queryInfo(mobile);
        if (response == null || response.isEmpty()) {
            return null;
        }
        Map<String, Object> result = (Map<String, Object>) response.get("result");
        // 号码归属地省份
        return (String) result.get("company");
    }

    /**
     * 查询手机号详情信息
     *
     * @param mobile the mobile
     * @return the mobile info
     */
    @SuppressWarnings("all")
    public static MobileInfo phoneNumberInfo(String mobile) {
        Map<String, Object> response = queryInfo(mobile);
        if (response == null || response.isEmpty()) {
            return null;
        }
        Map<String, Object> result = (Map<String, Object>) response.get("result");
        //{
        //    "zip":"310000",
        //    "province":"浙江",
        //    "city":"杭州",
        //    "company":"移动",
        //    "areacode":"0571",
        //    "card":""
        //}
        //System.err.println(JSON.toJSONString(result, true));
        return JSON.parseObject(JSON.toJSONString(result), MobileInfo.class);
    }

    private static Map<String, Object> queryInfo(String mobile) {
        if (mobile == null || mobile.trim().length() == 0) {
            return null;
        }
        Map<String, String> params = new HashMap<>();
        params.put("phone", mobile);
        params.put("key", key);
        Map<String, Object> response = JSON.parseObject(sendRequest(url, params));
        if (response == null || !"200".equals(response.get("resultcode"))) {
            return new HashMap<>(0);
        }
        return response;
    }

    @SuppressWarnings("all")
    private static String sendRequest(String url, Map<String, String> params) {
        if (url == null || url.trim().length() == 0) {
            return null;
        }
        DefaultHttpClient httpclient = new DefaultHttpClient();
        String body = null;
        StringBuilder queryUrl = new StringBuilder(url);
        if (params != null) {
            boolean first = true;
            for (String key : params.keySet()) {
                if (first) {
                    first = false;
                    queryUrl.append("?");
                } else {
                    queryUrl.append("&");
                }
                queryUrl.append(key).append("=").append(params.get(key));
            }
        }
        try {
            HttpGet get = new HttpGet(queryUrl.toString());
            httpclient.getParams().setParameter("http.useragent", "Mozilla/5.0 (X11; U; Linux i686; zh-CN; " +
                    "rv:1.9.1.2) Gecko/20090803 Fedora/3.5.2-2.fc11 Firefox/3.5.2");
            HttpResponse response = httpclient.execute(get);
            HttpEntity entity = response.getEntity();
            body = EntityUtils.toString(entity, "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            httpclient.getConnectionManager().shutdown();
        }
        return body;
    }

    /**
     * 手机号信息封装
     */
    public static class MobileInfo implements Serializable {
        private static final long serialVersionUID = -5739865235644588412L;

        private MobileInfo() {
            // 防止外边创建此类对象
        }

        private String zip;

        private String province;

        private String company;

        private String areacode;

        private String card;

        public String getZip() {
            return zip;
        }

        public void setZip(String zip) {
            this.zip = zip;
        }

        public String getProvince() {
            return province;
        }

        public void setProvince(String province) {
            this.province = province;
        }

        public String getCompany() {
            return company;
        }

        public void setCompany(String company) {
            this.company = company;
        }

        public String getAreacode() {
            return areacode;
        }

        public void setAreacode(String areacode) {
            this.areacode = areacode;
        }

        public String getCard() {
            return card;
        }

        public void setCard(String card) {
            this.card = card;
        }
    }

    public static void main(String[] args) {
//        boolean isPhoneNumber = isPhoneNumber("15268848628");
        String province = phoneNumberProvince("15268848628");
        String city = phoneNumberCity("15268848628");
//        String company = phoneNumberCompany("15268848628");
//        System.err.println(isPhoneNumber);
        System.err.println(province);
        System.err.println(city);
//        System.err.println(company);
//        System.err.println(phoneNumberProvince("18853415555"));
//        System.err.println(phoneNumberProvince("13507473196"));
//        MobileInfo mobileInfo = phoneNumberInfo("15268848628");
//        System.err.println(JSON.toJSONString(mobileInfo, true));

        //System.err.println(phoneNumberCompany("18555233775"));

//        System.out.println("MarketShop_13123131".split("MarketShop_")[1]);
    }

}
